package com.bestcem.xm.member.grpc.service;

import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.member.enums.ExtendFieldTypeEnum;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.grpc.service.param.extendfield.BatchUpdateFieldsParam;
import com.bestcem.xm.member.grpc.service.param.extendfield.InsertEnumItemParam;
import com.bestcem.xm.member.grpc.service.param.extendfield.InsertFieldParam;
import com.bestcem.xm.member.grpc.service.param.extendfield.UpdateFieldParam;
import com.bestcem.xm.member.grpc.v1.common.EmptyResponse;
import com.bestcem.xm.member.grpc.v1.common.ExtendField;
import com.bestcem.xm.member.grpc.v1.common.ExtendFieldEnumItem;
import com.bestcem.xm.member.grpc.v1.services.*;
import com.bestcem.xm.member.service.ExtendFieldService;
import com.bestcem.xm.member.service.dto.ExtendFieldDTO;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dc.wang <dc.wang@idiaoyan.com>
 * @version V1.0
 * @description TODO
 * @date 2021/7/21
 */
@GrpcService
public class ExtendFieldGrpcService extends ExtendFieldServiceGrpc.ExtendFieldServiceImplBase {
    private final ExtendFieldService extendFieldService;

    @Autowired
    public ExtendFieldGrpcService(ExtendFieldService extendFieldService){
        this.extendFieldService = extendFieldService;
    }

    @Override
    public void listEnumItems(ListEnumItemsRequest request, StreamObserver<ListEnumItemsResponse> responseObserver) {
        super.listEnumItems(request, responseObserver);
    }

    @Override
    public void batchUpdateExtendFields(BatchUpdateExtendFieldsRequest request, StreamObserver<EmptyResponse> responseObserver) {
        EmptyResponse.Builder builder = EmptyResponse.newBuilder();

        // 组装过滤参数
        String orgId = request.getOrgId();
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, request.getMemberTypeValue());

        BatchUpdateFieldsParam batchUpdateFieldsParam = new BatchUpdateFieldsParam();
        batchUpdateFieldsParam.setOrgId(orgId);
        batchUpdateFieldsParam.setDeleteFieldIds(request.getDeleteFieldIdsList());
        if(!CollectionUtils.isEmpty(request.getInsertFieldsList())){
            List<InsertFieldParam> insertFieldParams = request.getInsertFieldsList().stream().map(f -> this.convertFrom(memberTypeEnum, f)).collect(Collectors.toList());
            batchUpdateFieldsParam.setInsertFieldParams(insertFieldParams);
        }
        if(!CollectionUtils.isEmpty(request.getUpdateFieldsList())){
            List<UpdateFieldParam> updateFieldParams = request.getUpdateFieldsList().stream().map(f -> this.convertFrom(memberTypeEnum, f)).collect(Collectors.toList());
            batchUpdateFieldsParam.setUpdateFieldParams(updateFieldParams);
        }

        // 校验参数

        // 执行
        ServiceResult result = extendFieldService.batchUpdatedFields(batchUpdateFieldsParam);
        if(!result.isSuccess()){
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        builder.setStatus(RpcStatusResult.success());
        responseObserver.onNext(builder.build());
        responseObserver.onCompleted();
    }

    private InsertEnumItemParam convertFrom(ExtendFieldEnumItem extendFieldEnumItem){
        InsertEnumItemParam param = new InsertEnumItemParam();
        param.setFieldId(extendFieldEnumItem.getId());
        param.setName(extendFieldEnumItem.getName());
        param.setDisplayStatus(extendFieldEnumItem.getDisplay());
        return param;
    }

    private InsertFieldParam convertFrom(MemberTypeEnum memberTypeEnum,InsertExtendField insertExtendField){
        InsertFieldParam param = new InsertFieldParam();
        param.setMemberTypeEnum(EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberTypeEnum.getIndex()));
        param.setName(insertExtendField.getName());
        param.setExtendFieldTypeEnum(ExtendFieldTypeEnum.getByIndex(insertExtendField.getTypeValue()));
        if(!CollectionUtils.isEmpty(insertExtendField.getItemsList())){
            param.setInsertEnumItemParams(insertExtendField.getItemsList().stream().map(this::convertFrom).collect(Collectors.toList()));
        }
        return param;
    }

    private UpdateFieldParam convertFrom( MemberTypeEnum memberTypeEnum, UpdateExtendField updateExtendField){
        UpdateFieldParam param = new UpdateFieldParam();
        param.setMemberTypeEnum(memberTypeEnum);
        param.setId(updateExtendField.getId());
        param.setName(updateExtendField.getName());
        param.setExtendFieldTypeEnum(ExtendFieldTypeEnum.getByIndex(updateExtendField.getTypeValue()));
        if(!CollectionUtils.isEmpty(updateExtendField.getInsertItemsList())){
            param.setInsertEnumItemParams(updateExtendField.getInsertItemsList().stream().map(this::convertFrom).collect(Collectors.toList()));
        }
        if(!CollectionUtils.isEmpty(updateExtendField.getUpdateItemsList())){
            param.setInsertEnumItemParams(updateExtendField.getUpdateItemsList().stream().map(this::convertFrom).collect(Collectors.toList()));
        }
        if(!CollectionUtils.isEmpty(updateExtendField.getDeleteItemIdsList())){
            param.setDeleteEnumItemIds(updateExtendField.getDeleteItemIdsList());
        }
        return param;
    }

    private ExtendField convertFrom(ExtendFieldDTO extendFieldDTO){
        ExtendField.Builder builder = ExtendField.newBuilder();
        builder.setId(extendFieldDTO.getId());
        builder.setName(extendFieldDTO.getName());
        builder.setType(com.bestcem.xm.member.grpc.v1.enums.ExtendFieldTypeEnum.ExtendFieldType.forNumber(extendFieldDTO.getType()));
        return builder.build();
    }
}
